#include "linker.h"

bool Linker::AllConditionSatisfy()
{
    for(int i = 0;i < conditions.count();i++)
    {
        if(!ConditionSatisfy(conditions.at(i)))
            return false;
    }
    return true;
}

bool Linker::ConditionSatisfy(Condition *c)
{
    //> = < >= <=
    //判断条件是否满足
    if(!c)
        return false;
    return IntConditionSatisfy(c) || StringConditionSatisfy(c) || FloatConditionSatisfy(c) || BoolConditionSatisfy(c);
}

bool Linker::IntConditionSatisfy(Condition *c)
{
    if(c->data.dataType != INT_ || !GameData::Instance().intData.contains(c->key))
        return false;
    int value = GameData::Instance().intData[c->key];
    int data = c->data.i;
    switch(c->symbol)
    {
    case EQUAL:
        return value == data;
        break;
    case BIGGER:
        return value > data;
        break;
    case LESS:
        return value < data;
        break;
    case BIGGEROREQUAL:
        return value >= data;
        break;
    case LESSOREQUAL:
        return value < data;
        break;
    default:break;
    }
    return false;
}

bool Linker::StringConditionSatisfy(Condition *c)
{
    if(c->data.dataType != STRING_ || !GameData::Instance().stringData.contains(c->key))
        return false;
    QString value = GameData::Instance().stringData[c->key];
    QString data = c->data.s;
    switch(c->symbol)
    {
    case EQUAL:
        return value == data;
        break;
    case BIGGER:
        return value.count() > data.count();
        break;
    case LESS:
        return value.count() < data.count();
        break;
    case BIGGEROREQUAL:
        return value.count() >= data.count();
        break;
    case LESSOREQUAL:
        return value.count() < data.count();
        break;
    default:break;
    }
    return false;
}

bool Linker::FloatConditionSatisfy(Condition *c)
{
    if(c->data.dataType != FLOAT_ || !GameData::Instance().floatData.contains(c->key))
        return false;
    float value = GameData::Instance().floatData[c->key];
    float data = c->data.f;
    switch(c->symbol)
    {
    case EQUAL:
        return value == data;
        break;
    case BIGGER:
        return value > data;
        break;
    case LESS:
        return value < data;
        break;
    case BIGGEROREQUAL:
        return value >= data;
        break;
    case LESSOREQUAL:
        return value < data;
        break;
    default:break;
    }
    return false;
}

bool Linker::BoolConditionSatisfy(Condition *c)
{
    if(c->data.dataType != BOOL_ || !GameData::Instance().boolData.contains(c->key))
        return false;
    bool value = GameData::Instance().boolData[c->key];
    bool data = c->data.b;
    return value == data;
}

bool Linker::HandleAllAction()
{
    bool res = true;
    for(int i = 0; i < actions.count(); i++)
    {
        res &= HandleAction(actions[i]);
    }
    return res;
}

bool Linker::HandleAction(Action *a)
{
    //执行ACtion
    //加减乘除，赋值
    if(!a)
        return false;
    return IntAction(a) || StringAction(a) || FloatAction(a) || BoolAction(a);
}

bool Linker::IntAction(Action *a)
{
    if(a->data.dataType != INT_ || !GameData::Instance().intData.contains(a->key))
        return false;
    int value = GameData::Instance().intData[a->key];
    int data = a->data.i;
    switch(a->act)
    {
    case EQU:
        value = data;
        break;
    case ADD:
        value += data;
        break;
    case SUB:
        value -= data;
        break;
    case MUL:
        value *= data;
        break;
    case DIV:
        if(data == 0)
            return false;
        value /= data;
        break;
    default:break;
    }
    GameData::Instance().intData[a->key] = value;
    return true;
}

bool Linker::StringAction(Action *a)
{
    if(a->data.dataType != STRING_ || !GameData::Instance().stringData.contains(a->key))
        return false;
    QString value = GameData::Instance().stringData[a->key];
    QString data = a->data.s;
    switch(a->act)
    {
    case EQU:
        value = data;
        break;
    case ADD:
        value += data;
        break;
    case SUB:
        return false;
        break;
    case MUL:
        return false;
        break;
    case DIV:
        return false;
        break;
    default:break;
    }
    GameData::Instance().stringData[a->key] = value;
    return true;
}

bool Linker::FloatAction(Action *a)
{
    if(a->data.dataType != FLOAT_ || !GameData::Instance().floatData.contains(a->key))
        return false;
    float value = GameData::Instance().floatData[a->key];
    float data = a->data.f;
    switch(a->act)
    {
    case EQU:
        value = data;
        break;
    case ADD:
        value += data;
        break;
    case SUB:
        value -= data;
        break;
    case MUL:
        value *= data;
        break;
    case DIV:
        if(data == 0.0f)
            return false;
        value /= data;
        break;
    default:break;
    }
    GameData::Instance().floatData[a->key] = value;
    return true;
}

bool Linker::BoolAction(Action *a)
{
    if(a->data.dataType != BOOL_ || !GameData::Instance().boolData.contains(a->key))
        return false;
    GameData::Instance().intData[a->key] = a->data.b;
    return true;
}

Linker::Linker()
{

}

Linker::~Linker()
{
    for(int i = 0;i < conditions.count(); i++)
    {
        delete conditions.at(i);
    }
    conditions.clear();
    for(int i = 0;i < actions.count(); i++)
    {
        delete actions.at(i);
    }
    actions.clear();
}
